package cn.yx.common.core.controller;

import cn.yx.common.core.pojo.IdCond;
import cn.yx.common.core.pojo.IdListCond;
import cn.yx.common.core.pojo.PageVo;
import cn.yx.common.core.pojo.ResponseVo;
import cn.yx.common.core.pojo.singletable.SingleCond;
import cn.yx.common.core.pojo.singletable.SingleInVo;
import cn.yx.common.core.pojo.singletable.SingleOutVo;

import java.io.Serializable;
import java.util.List;

/**
 * <p>BaseAdminController接口，仅用作后台管理的Controller接口，操作单表</p>
 *
 * @param <InVo>  VO输入类
 * @param <OutVo> VO输出类
 * @param <Cond>  Cond类
 * @param <Id>    ID主键值类
 * @author Wgssmart
 */
public interface BaseAdminController<InVo extends SingleInVo,
        OutVo extends SingleOutVo,
        Cond extends SingleCond,
        Id extends Serializable> {

    /**
     * 保存单条数据
     *
     * @param inVo 需要保存的数据
     * @return
     */
    ResponseVo<Void> save(InVo inVo);

    /**
     * 批量保存数据
     *
     * @param inVoList 需要批量保存的数据列表
     * @return
     */
    ResponseVo<Void> save(List<InVo> inVoList);

    /**
     * 根据主键判断数据是否存在，如果不存在则插入，存在则更新
     *
     * @param inVo 需要更新或保存的数据
     * @return
     */
    ResponseVo<Void> saveOrUpdate(InVo inVo);

    /**
     * 根据updateCond来判断是否更新数据，规则：
     * 如果满足updateCond条件，则更新数据（可能有多条满足条件的数据被更新成指定的DTO数据），否则插入DTO对应的一条记录。
     *
     * @param inVo       如果是更新数据，则更新为VO指定的数据，否则插入VO数据
     * @param updateCond 按此条件对象来更新数据，如果不符合此条件条件，则执行saveOrUpdateOne(Vo vo)方法
     * @return
     */
    ResponseVo<Void> saveOrUpdate(InVo inVo, Cond updateCond);

    /**
     * 批量保存或更新，根据主键判断数据是否存在
     *
     * @param inVoList 需要批量更新或保存的数据列表
     * @return
     */
    ResponseVo<Void> saveOrUpdate(List<InVo> inVoList);

    /**
     * 根据主键删除单条数据
     *
     * @param idCond 主键值
     * @return
     */
    ResponseVo<Void> remove(IdCond<Id> idCond);

    /**
     * 根据多个主键批量删除多条数据
     *
     * @param idListCond 主键值列表
     * @return
     */
    ResponseVo<Void> remove(IdListCond<Id> idListCond);

    /**
     * 根据条件删除数据
     *
     * @param deleteCond 删除数据的条件对象
     * @return
     */
    ResponseVo<Void> remove(Cond deleteCond);

    /**
     * 根据主键id更新数据，属性为null的，更新时会被忽略（字段不会被更新为null）。使用了乐观锁version字段
     *
     * @param inVo 需要更新的数据对象，必须包含主键值
     * @return
     */
    ResponseVo<Void> update(InVo inVo);

    /**
     * 根据主键id批量更新数据，属性为null的，更新时会被忽略（字段不会被更新为null）
     *
     * @param inVoList 需要批量更新的数据对象，必须包含主键值
     * @return
     */
    ResponseVo<Void> update(List<InVo> inVoList);

    /**
     * 根据条件更新数据（可能更新多条满足条件的数据），dto中指定的属性为null时，字段不会被更新为null
     *
     * @param inVo       把数据更新成VO中指定的数据
     * @param updateCond 更新数据的条件对象，按照此条件来更新数据
     * @return
     */
    ResponseVo<Void> update(InVo inVo, Cond updateCond);

    /**
     * 更新数据，如果DTO中的属性为null，则字段更新为null
     *
     * @param inVo 把数据更新成VO中指定的数据，如果属性为null，字段也更新为null
     * @return
     */
    ResponseVo<Void> updateAllColumn(InVo inVo);

    /**
     * 批量更新数据，如果DTO中的属性为null，则字段更新为null
     *
     * @param inVoList 把数据更新成DTO中指定的数据，如果属性为null，字段也更新为null
     * @return
     */
    ResponseVo<Void> updateAllColumn(List<InVo> inVoList);

    /**
     * 根据条件更新数据，如果DTO中的属性为null，则字段更新为null
     *
     * @param inVo       把数据更新成VO中指定的数据，如果属性为null，字段也更新为null
     * @param updateCond 更新数据的条件对象，按照此条件来更新数据
     * @return
     */
    ResponseVo<Void> updateAllColumn(InVo inVo, Cond updateCond);

    /**
     * 根据主键查询单个数据
     *
     * @param idCond 主键值
     * @return
     */
    ResponseVo<OutVo> getOne(IdCond<Id> idCond);

    /**
     * 根据 SelectCondObj，查询一条记录。结果集，如果是多个会抛出异常
     *
     * @param selectCond 查询条件
     * @return
     */
    ResponseVo<OutVo> getOne(Cond selectCond);

    /**
     * 查询所有
     *
     * @return
     */
    ResponseVo<PageVo<OutVo>> listAll();

    /**
     * 条件查询所有
     *
     * @param selectCond 查询条件
     * @return
     */
    ResponseVo<PageVo<OutVo>> listAll(Cond selectCond);

    /**
     * 根据多个主键id批量查询
     *
     * @param idListCond 主键值列表
     * @return
     */
    ResponseVo<PageVo<OutVo>> listAll(IdListCond<Id> idListCond);

    /**
     * 条件分页查询
     *
     * @param pageCond 分页对象
     * @return
     */
    ResponseVo<PageVo<OutVo>> page(Cond pageCond);

    /**
     * 查询总记录数
     *
     * @return
     */
    ResponseVo<Long> count();

    /**
     * 根据条件查询总记录数
     *
     * @param selectCond 查询条件
     * @return
     */
    ResponseVo<Long> count(Cond selectCond);

}
